 # -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyKDE4.plasma import Plasma
from PyKDE4 import plasmascript 
from PyKDE4.kdecore import KConfigGroup, KUrl 
from PyKDE4.kdeui import KMessageBox
from PyKDE4.phonon import Phonon
from lastfm import LastFMConnection, LastFMError
from PyKDE4.kio import KRun

class SessionKeyDialog(QDialog):

	def __init__(self, link):

		QDialog.__init__(self)
		self.link = link

		self.setWindowTitle('request last.fm session key')
		
		message = 'Visit <a href="' + link + '">this link</a> to permanently allow streaming music<br/> from last.fm to the plasmoid. Do <b>not</b> hit OK before you<br/>granted the plasmoid permission on the last.fm page.'
		
		buttons = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self)
		self.connect(buttons, SIGNAL('accepted()'), self.emitOk)
		label = QLabel(self)
		label.setText(message)
		self.connect(label, SIGNAL('linkActivated(QString)'), self.openLinkInBrowser)
		layout = QVBoxLayout()
		layout.addWidget(label)
		layout.addWidget(buttons)
		self.setLayout(layout)

	def emitOk(self):

		self.emit(SIGNAL('ok()'))

	def openLinkInBrowser(self, link):

		KRun.runUrl(KUrl(link), 'text/html', None)

class LastFMPlasmoid(plasmascript.Applet):
	
	currentTrack = None
	tracks = None
	mediaObject = None
	playing = False
	lastfm = None

	def __init__(self,parent,args=None):
		plasmascript.Applet.__init__(self,parent)

		self.lastfm = LastFMConnection()

	def init(self):

		self.setAspectRatioMode(Plasma.IgnoreAspectRatio)
		self.setHasConfigurationInterface(True)
		self.theme = Plasma.Svg(self)
		self.theme.setImagePath("widgets/background")
		self.setBackgroundHints(Plasma.Applet.DefaultBackground)

		self.skipButton = Plasma.PushButton(self.applet)
		self.skipButton.setText('skip')
		self.skipButton.setEnabled(False)
		self.connect(self.skipButton, SIGNAL('clicked()'), self.playNextTrack)

		self.playStopButton = Plasma.PushButton(self.applet)
		self.playStopButton.setText('play')
		self.connect(self.playStopButton, SIGNAL('clicked()'), self.playStop)

		self.trackLabel = Plasma.Label(self.applet)
		self.trackLabel.setText('<artist> - <title>')
		
		layout = QGraphicsLinearLayout(Qt.Horizontal, self.applet)
		layout.addItem(self.trackLabel)
		layout.addItem(self.playStopButton)
		layout.addItem(self.skipButton)

		self.setLayout(layout)
		self.resize(300, 60)

		#print self.readStation()

	def createPlayer(self, source):
		
		self.mediaObject = Phonon.createPlayer(Phonon.MusicCategory, source)
		self.connect(self.mediaObject, SIGNAL('finished()'), self.playNextTrack)
		self.connect(self.mediaObject, SIGNAL('stateChanged(Phonon::State, Phonon::State)'), self.changeLabel)

	def __del__(self):

		if self.mediaObject != None:
			self.mediaObject.stop()
		
	def getSessionKey(self):

		self.sessionKeyDialog.hide()

		try:

			sessionKey = self.lastfm.getSessionKey()

		except LastFMError as e:

			KMessageBox.error(None, str(e), 'last.fm authentication')
			return

		# safe session key

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')
		sessionKeysGroup = lastfmGroup.group('sessionkeys')

		username = self.readUsername()
		sessionKeysGroup.writeEntry(username, sessionKey)

		# start music

		self.playStop()

	def requestSessionKey(self):

		try:

			self.lastfm.requestToken()

		except LastFMError as e:

			KMessageBox.error(None, str(e), 'last.fm authentication')
			return

		link = 'http://www.last.fm/api/auth/?api_key='+self.lastfm.apiKey+'&token='+self.lastfm.token
		
		self.sessionKeyDialog = SessionKeyDialog(link)
		self.sessionKeyDialog.show()
		self.connect(self.sessionKeyDialog, SIGNAL('ok()'), self.getSessionKey)

	def readSessionKey(self, username):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')
		sessionKeysGroup = lastfmGroup.group('sessionkeys')

		sessionKey = sessionKeysGroup.readEntry(username,'')

		if sessionKey == '':
			return None
		else:
			return sessionKey

	def readUsername(self):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')

		username = lastfmGroup.readEntry('username','')

		if username == '':
			return None
		else:
			return username

	def readStation(self):

		configGroup = self.config()
		lastfmGroup = configGroup.group('lastfm')

		similarartists = lastfmGroup.readEntry('similarartists','true')

		if similarartists == 'true':
			
			artist = lastfmGroup.readEntry('artist','minor threat')
			return {'station':'similarartists', 'artist':artist}	
		topfans = lastfmGroup.readEntry('topfans','false')

		if topfans == 'true':

			artist = lastfmGroup.readEntry('topfans_artist','minor threat')
			return {'station':'topfans', 'artist':artist}
		library = lastfmGroup.readEntry('library','false')

		if library == 'true':
			
			username = self.readUsername()
			return {'station':'library', 'username':username}
		neighbours = lastfmGroup.readEntry('neighbours','false')

		if neighbours == 'true':
			
			username = self.readUsername()
			return {'station':'neighbours', 'username':username}
		lovedtracks = lastfmGroup.readEntry('lovedtracks','false')

		if lovedtracks == 'true':
			
			username = self.readUsername()
			return {'station':'lovedtracks', 'username':username}
		recommendations = lastfmGroup.readEntry('recommendations','false')

		if recommendations == 'true':
			
			username = self.readUsername()
			return {'station':'recommendations', 'username':username}
		tag = lastfmGroup.readEntry('tag','false')

		if tag == 'true':
			
			tag = lastfmGroup.readEntry('tag_tag','freak folk')
			return {'station':'tag', 'tag':tag}

	def play(self):

		if self.readConfig() == False:

			return

		try:
			
			self.setStation()
			self.tracks = self.lastfm.getTracks()
		except LastFMError as e:

			KMessageBox.error(None, str(e), 'last.fm error')
			return	

		self.playing = True;
		self.playStopButton.setText('stop')
		self.skipButton.setEnabled(True)
	
		self.playNextTrack()

	def stop(self):

		self.playing = False;
		self.playStopButton.setText('play')
		self.skipButton.setEnabled(False)
		self.mediaObject.stop()

	def playStop(self):

		if self.playing == False:

			self.play()
		else:

			self.stop()

	def setStation(self):

		station = self.readStation()

		if station['station'] == 'similarartists':

			artist = station['artist']
			self.lastfm.tuneSimilarArtistsRadio(str(artist))
		elif station['station'] == 'topfans':

			artist = station['artist']
			self.lastfm.tuneTopFansRadio(str(artist))
		elif station['station'] == 'lovedtracks':

			username = station['username']
			self.lastfm.tuneLovedRadio(str(username))
		elif station['station'] == 'neighbours':

			username = station['username']
			self.lastfm.tuneNeighboursRadio(str(username))
		elif station['station'] == 'library':

			username = station['username']
			self.lastfm.tuneLibraryRadio(str(username))
		elif station['station'] == 'recommendations':

			username = station['username']
			self.lastfm.tuneLovedRadio(str(username))
		elif station['station'] == 'tag':

			tag = station['tag']
			self.lastfm.tuneTagRadio(str(tag))

	def changeLabel(self, new, old):

		if new == Phonon.PlayingState:
			self.trackLabel.setText(self.currentTrack.artist+' - '+self.currentTrack.title)
		else:
			self.trackLabel.setText('<artist> - <title>')

	def readConfig(self):
		
		# read username, if not present activate 'config required' thingie.

		username = self.readUsername()
		if username == None:
			self.setConfigurationRequired(True, 'Initial Configuration required.')
			return False
		
		self.setConfigurationRequired(False, '')

		# read session key for that username, if not present open dialog
		# w/ permission link to last.fm requestSessionKey

		sessionKey = self.readSessionKey(username)
		if sessionKey == None:
			self.requestSessionKey()
			return False

		# config ok

		self.lastfm.sessionKey = str(sessionKey)
		self.setConfigurationRequired(False, '')
		
		return True

	def configChanged(self):

		self.readConfig()

	def playNextTrack(self):
		
		self.currentTrack = self.tracks.pop(0)

		if self.mediaObject == None:

			self.createPlayer(self.currentTrack)
		else:

			self.mediaObject.stop()
			self.mediaObject.setCurrentSource(self.currentTrack)
		
		self.mediaObject.play()

		self.trackLabel.setText(self.currentTrack.artist+' - '+self.currentTrack.title)

		if len(self.tracks) == 0:
		
			try:

				self.tracks = self.lastfm.getTracks()
			except LastFMError as e:

				KMessageBox.error(None, str(e), 'last.fm error')
				self.stop()
		

def CreateApplet(parent):
	return LastFMPlasmoid(parent)